/**
 * Copyright (c) Huawei Technologies Co., Ltd. 1987-2021. All rights reserved.
*/

package com.gitee.fufu669.aspect;

import com.gitee.fufu669.common.CacheKeyCommon;
import com.gitee.fufu669.config.exception.CacheServerErrorCode;
import com.gitee.fufu669.config.exception.CacheServerException;
import com.gitee.fufu669.service.CacheService;
import com.gitee.fufu669.utils.CacheAopUtil;
import com.gitee.fufu669.utils.CacheJsonUtil;
import com.gitee.fufu669.utils.CacheNetworkUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

/**
 * @author wangfupeng on 2017-5-6.
 */
@Aspect
// 组件注解
@Component
// 注解
@Order(-67)
// 注解
@SuppressWarnings({"rawtypes"})
/**
 * TODO
*/
public class CheckVisitFrequencyAop {

    /**
     * TODO
    */
    public static final Logger logger = LoggerFactory.getLogger(CheckVisitFrequencyAop.class);

    // 注解
    @Autowired
    // TODO
    private HttpServletRequest request;

    // 注解
    @Autowired
    // TODO
    private CacheService cacheService;

    // 注解
    @Before("@annotation(com.gitee.fufu669.aspect.CheckVisitFrequency)")
    /**
     * TODO
    */
    public void aroundMethod(JoinPoint joinPoint) {
        // 赋值
        Integer frequencyNumber = null;
        // 赋值
        Integer secondsNumber = null;
        // 赋值
        String methodName = null;
        // 赋值
        String formulaString = "";
        // 赋值
        String description = "";
        // 赋值
        String[] parameterNames = {};
        // 尝试下面的代码
        try {
            // 字符串赋值
            String targetName = joinPoint.getTarget().getClass().getName();
            // TODO
            methodName = joinPoint.getSignature().getName();
            // TODO
            Class targetClass = Class.forName(targetName);
            // TODO
            Method[] methods = targetClass.getMethods();
            // 遍历
            for (Method method : methods) {
                // 判断
                if (method.getName().equals(methodName)) {
                    // TODO
                    formulaString = method.getAnnotation(CheckVisitFrequency.class).formula();
                    // TODO
                    description = method.getAnnotation(CheckVisitFrequency.class).description();
                    // TODO
                    parameterNames = method.getAnnotation(CheckVisitFrequency.class).parameterNames();
                    // 跳出
                    break;
                }
            }
            // 判断
            if (StringUtils.isEmpty(formulaString)) {
                // 赋值
                formulaString = CacheKeyCommon.CHECKVISITFREQUENCY_LIMIT_VISIT_FORMULA;
            }
            // 切分
            String[] fromulas = formulaString.split(", ");
            // 转换值
            secondsNumber = Integer.valueOf(fromulas[0]);
            // 转换值
            frequencyNumber = Integer.valueOf(fromulas[1]);
        // 捕捉异常
        } catch (Exception e) {
            // 抛出异常
            throw new CacheServerException(CacheServerErrorCode.CHECKVISITFREQUENCYAOP_LIMIT_PROGRAM_AOP_PREFERENCE_ERROR);
        }
        // 字符串赋值
        String token = request.getHeader("token");
        // 判断是否是空
        if (token == null) {
            // TODO
            token = CacheNetworkUtil.getIpAddr(request);
        }
        // 判断
        if (secondsNumber > 0 && frequencyNumber > 0) {
            // 字符串赋值
            String cacheKeyCheckVisitFrequency = CacheKeyCommon.REDIS_KEY_CHECKVISITFREQUENCY + "lock:" + CacheAopUtil.getCacheKey(joinPoint, parameterNames) + ":" + token;
            // 判断是否是空
            if (cacheService.get(cacheKeyCheckVisitFrequency) == null) {
                // TODO
                cacheService.incrby(cacheKeyCheckVisitFrequency, 1);
                // TODO
                cacheService.expire(cacheKeyCheckVisitFrequency, secondsNumber);
            // 否则
            } else {
                // 判断
                if (cacheService.ttl(cacheKeyCheckVisitFrequency).equals(-1L)) {
                    // TODO
                    cacheService.expire(cacheKeyCheckVisitFrequency, secondsNumber);
                }
                // TODO
                Long visitTimes = cacheService.incrby(cacheKeyCheckVisitFrequency, 1);
                // TODO
                cacheService.expire(cacheKeyCheckVisitFrequency, secondsNumber);
                // 判断
                if (visitTimes > frequencyNumber) {
                    // 判断
                    if (!"".equals(description)) {
                        // 赋值
                        description = " " + description + " ";
                    }
                    // 抛出异常
                    throw new CacheServerException(CacheServerErrorCode.CHECKVISITFREQUENCYAOP_CAN_NOT_VISIT_THIS_RESOURCE_WITH_SECONDS, secondsNumber, frequencyNumber, visitTimes, description);
                }
            }
        }
        logger.info("CheckVisitFrequencyAop:通过验证:methodName:" + methodName + ":formula:" + formulaString+":parameterNames:"+ CacheJsonUtil.toJson(parameterNames) + ":description:" + description);
    }

}
